package de.karlNet.login.attributeMapper;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

import javax.naming.NamingException;
import javax.naming.directory.Attributes;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import de.karlNet.sambamanager.ldapModel.LdapObject;
import de.karlNet.sambamanager.ldapModel.dns.LdapDNSARecord;
import de.karlNet.sambamanager.ldapModel.dns.LdapDNSCName;

@Component
public class DnsNodeExtractor extends LdapObjectExtractor {

	@Autowired
	private DnsZoneExtractor dnsZoneExtractor;


	private LdapObject getLdapDNSRecord(Attributes attributes)
			throws NamingException {
		String dn = this.tryToGetString("distinguishedname", attributes,
				tryToGetString("dn", attributes));
		String dc = this.tryToGetString("dc", attributes,
				tryToGetString("dc", attributes));

		byte[] dnsRecordTmp = (byte[]) attributes.get("dnsRecord").get();
		int[] dnsRecord = new int[dnsRecordTmp.length];
		for (int i = 0; i < dnsRecordTmp.length; i++) {
			dnsRecord[i] = dnsRecordTmp[i] & 0xFF;
		}
		switch (dnsRecord[2]) {
		// CNAME
		case 5: {
			int totalLength = dnsRecord[24];
			List<String> cnameComponents = new ArrayList<String>();
			for (int i = 2; i < totalLength; i++) {
				int subElementLength = dnsRecord[i + 24];
				String aliasPart = "";
				for (int j = 1; j <= subElementLength; j++) {
					aliasPart += "" + (char) (dnsRecord[i + j + 24]);
				}
				cnameComponents.add(aliasPart);
				i += subElementLength;
			}
			ByteBuffer wrapper = ByteBuffer.wrap(new byte[] { dnsRecordTmp[12],
					dnsRecordTmp[13], dnsRecordTmp[14], dnsRecordTmp[15] });
			int ttl = wrapper.getInt();
			String alias = StringUtils.join(cnameComponents, ".");
			return new LdapDNSCName(dc, dn, alias, ttl);
		}
		// AAAA
		case 28:
			break;
		// A record
		case 1: {
			ByteBuffer wrapper = ByteBuffer.wrap(new byte[] { dnsRecordTmp[12],
					dnsRecordTmp[13], dnsRecordTmp[14], dnsRecordTmp[15] });
			int ttl = wrapper.getInt();
			Integer[] ipAddressArray = new Integer[4];
			for (int i = 24; i < 28; i++) {
				ipAddressArray[i - 24] = dnsRecord[i];
			}
			String ipAddress = StringUtils.join(ipAddressArray, ".");

			return new LdapDNSARecord(dc, dn, ipAddress, ttl);
		}
		default:
			return new LdapDNSARecord(dc, dn, "", 0);
		}
		return null;

	}
	
	@Override
	public LdapObject extract(Attributes attributes, List<String> objectClasses)
			throws NamingException {
		if (objectClasses.contains("dnsNode")) {
			return this.getLdapDNSRecord(attributes);
		}
		return null;
	}
}
